import fs from 'node:fs'
import { fileURLToPath, URL } from 'node:url'
import * as parserVue from 'vue-eslint-parser'
import js from '@eslint/js'
import configPrettier from 'eslint-config-prettier'
import * as pluginImport from 'eslint-plugin-import-x'
import pluginPerfectionist from 'eslint-plugin-perfectionist'
import pluginPrettier from 'eslint-plugin-prettier'
import * as regexpPlugin from 'eslint-plugin-regexp'
import pluginVue from 'eslint-plugin-vue'
import { defineConfig, globalIgnores } from 'eslint/config'
import globals from 'globals'
import tseslint from 'typescript-eslint'

const autoImportPath = fileURLToPath(new URL('.eslintrc-auto-import.json', import.meta.url))
const eslintrcAutoImport = JSON.parse(fs.readFileSync(autoImportPath, 'utf8'))

export default defineConfig([
  globalIgnores([
    '**/node_modules',
    '**/dist',
    '**/dist-*',
    '**/*-dist',
    '**/.husky',
    '**/.nitro',
    '**/.output',
    '**/Dockerfile',
    '**/package-lock.json',
    '**/yarn.lock',
    '**/pnpm-lock.yaml',
    '**/bun.lockb',
    '**/output',
    '**/coverage',
    '**/temp',
    '**/.temp',
    '**/tmp',
    '**/.tmp',
    '**/.history',
    '**/.turbo',
    '**/.nuxt',
    '**/.next',
    '**/.vercel',
    '**/.changeset',
    '**/.idea',
    '**/.cache',
    '**/.output',
    '**/.vite-inspect',
    '**/CHANGELOG*.md',
    '**/*.min.*',
    '**/LICENSE*',
    '**/__snapshots__',
    '**/*.snap',
    '**/fixtures/**',
    '**/.vitepress/cache/**',
    '**/auto-import?(s).d.ts',
    '**/components.d.ts',
    '**/vite.config.mts.*',
    '**/*.sh',
    '**/*.ttf',
    '**/*.woff'
  ]),
  {
    ...js.configs.recommended,
    languageOptions: {
      ecmaVersion: 'latest',
      globals: {
        ...globals.browser,
        ...globals.es2021,
        ...globals.node,
        document: 'readonly',
        navigator: 'readonly',
        window: 'readonly'
      },
      parserOptions: {
        ecmaFeatures: {
          jsx: true
        },
        ecmaVersion: 'latest',
        sourceType: 'module'
      },
      sourceType: 'module',
      ...eslintrcAutoImport
    },
    plugins: {
      prettier: pluginPrettier,
      import: pluginImport,
      perfectionist: pluginPerfectionist,
      regexp: regexpPlugin
    },
    rules: {
      ...configPrettier.rules,
      ...pluginPrettier.configs.recommended.rules,
      'no-debugger': 'off',
      'no-unused-vars': [
        'error',
        {
          argsIgnorePattern: '^_',
          varsIgnorePattern: '^_'
        }
      ],
      'prettier/prettier': 'error',
      'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], // 强制使用统一的类型指定风格，推荐使用顶层类型指定
      'import/first': 'error', // 强制导入语句排在文件的最前面
      'import/newline-after-import': 'error', // 强制导入语句后要有空行
      'import/no-duplicates': 'error', // 禁止导入重复的模块
      'import/no-mutable-exports': 'error', // 禁止导出可变的内容
      'import/no-named-default': 'error', // 禁止命名默认导出
      'import/no-self-import': 'error', // 禁止模块自我导入
      'import/no-unresolved': 'off', // 禁用 unresolved 模块检查
      'import/no-webpack-loader-syntax': 'error', // 禁止使用 Webpack loader 语法在导入中
      // 对导出进行排序
      'perfectionist/sort-exports': [
        'error',
        {
          order: 'asc', // 按照升序排序
          type: 'natural' // 自然排序（例如：a2 < a10）
        }
      ],

      // 对 import 语句排序
      'perfectionist/sort-imports': [
        'error',
        {
          customGroups: {
            // 自定义类型导入的分组（例如：import type { X } from '...'）
            type: {
              '@-type': ['^@/.+'], // 匹配 @ 开头的类型导入
              'vue-type': ['^vue$', '^vue-.+', '^@vue/.+'] // 匹配 Vue 相关的类型导入
            },
            // 实际导入语句的分组（非 type）
            value: {
              '@-value': ['^@/.+'],
              vue: ['^vue$', '^vue-.+', '^@vue/.+']
            }
          },
          environment: 'node', // 环境为 Node.js，会影响 builtin 判断
          groups: [
            // 类型导入的分组顺序
            ['external-type', 'builtin-type', 'type'], // 第1组：外部类型、内建类型、通用类型导入
            'vue-type', // 第2组：Vue 类型
            '@-type', // 第3组：vben 类型
            ['parent-type', 'sibling-type', 'index-type'], // 第4组：相对路径类型导入
            ['internal-type'], // 第5组：内部别名路径类型导入

            // 实际导入语句的分组顺序
            'builtin', // Node.js 内建模块，如 fs、path 等
            'vue', // vue 相关库
            '@-value', // @ 相关库
            'external', // 外部依赖
            'internal', // 项目内别名路径（例如 `#` 开头）

            ['parent', 'sibling', 'index'], // 相对路径导入：../、./等
            'side-effect', // 副作用导入：如 import './style.css'
            'side-effect-style', // 专门的样式副作用导入
            'style', // 样式文件导入
            'object', // import obj from 'obj'
            'unknown' // 未分类导入
          ],
          internalPattern: ['^@/.+'], // 匹配内部模块（如使用别名 `@` 开头）
          newlinesBetween: 'ignore', // 每组导入之间空一行
          order: 'asc', // 升序
          type: 'natural' // 自然排序
        }
      ],

      // 关闭对模块列表（如 require）排序
      'perfectionist/sort-modules': 'off',

      // 对命名导出（named exports）排序
      'perfectionist/sort-named-exports': [
        'error',
        {
          order: 'asc', // 升序
          type: 'natural' // 自然排序
        }
      ],

      // 对对象中的属性排序（此规则被关闭）
      'perfectionist/sort-objects': [
        'off',
        {
          customGroups: {
            items: 'items', // 自定义组名
            list: 'list',
            children: 'children'
          },
          groups: ['unknown', 'items', 'list', 'children'], // 分组排序顺序
          ignorePattern: ['children'], // 忽略 children 组中的排序
          order: 'asc',
          type: 'natural'
        }
      ]
    }
  },
  ...tseslint.config({
    extends: [...tseslint.configs.recommended],
    files: ['**/*.?([cm])ts', '**/*.?([cm])tsx'],
    rules: {
      '@typescript-eslint/no-redeclare': 'error',
      '@typescript-eslint/ban-ts-comment': 'off',
      '@typescript-eslint/no-explicit-any': 'off',
      '@typescript-eslint/prefer-as-const': 'warn',
      '@typescript-eslint/no-empty-function': 'off',
      '@typescript-eslint/no-non-null-assertion': 'off',
      '@typescript-eslint/no-unused-expressions': 'off',
      '@typescript-eslint/no-unsafe-function-type': 'off',
      '@typescript-eslint/no-import-type-side-effects': 'error',
      '@typescript-eslint/explicit-module-boundary-types': 'off',
      '@typescript-eslint/consistent-type-imports': ['error', { disallowTypeAnnotations: false, fixStyle: 'inline-type-imports' }],
      '@typescript-eslint/prefer-literal-enum-member': ['error', { allowBitwiseExpressions: true }],
      '@typescript-eslint/no-unused-vars': 'off',
      '@typescript-eslint/no-empty-object-type': 'off'
    }
  }),
  {
    files: ['**/*.d.ts'],
    rules: {
      'eslint-comments/no-unlimited-disable': 'off',
      'import/no-duplicates': 'off',
      'no-restricted-syntax': 'off',
      'unused-imports/no-unused-vars': 'off'
    }
  },
  {
    files: ['**/*.?([cm])js'],
    rules: {
      '@typescript-eslint/no-require-imports': 'off'
    }
  },
  {
    files: ['**/*.vue'],
    languageOptions: {
      globals: {},
      parser: parserVue,
      parserOptions: {
        ecmaFeatures: {
          jsx: true
        },
        extraFileExtensions: ['.vue'],
        parser: tseslint.parser,
        sourceType: 'module'
      }
    },
    plugins: {
      '@typescript-eslint': tseslint.plugin,
      vue: pluginVue
    },
    processor: pluginVue.processors['.vue'],
    rules: {
      ...pluginVue.configs.base.rules,
      ...pluginVue.configs.essential.rules,
      ...pluginVue.configs.recommended.rules,

      'vue/attribute-hyphenation': [
        'error',
        'never',
        {
          ignore: []
        }
      ],
      'vue/attributes-order': 'off',
      'vue/block-order': [
        'error',
        {
          order: ['template', 'script', 'style']
        }
      ],
      'vue/component-name-in-template-casing': ['error', 'PascalCase'],
      'vue/component-options-name-casing': ['error', 'PascalCase'],
      'vue/custom-event-name-casing': ['error', 'camelCase'],
      'vue/define-macros-order': [
        'error',
        {
          order: ['defineOptions', 'defineProps', 'defineEmits', 'defineSlots']
        }
      ],
      'vue/dot-location': ['error', 'property'],
      'vue/dot-notation': ['error', { allowKeywords: true }],
      'vue/eqeqeq': ['error', 'smart'],
      'vue/html-closing-bracket-newline': 'error',
      'vue/html-indent': 'off',
      // 'vue/html-indent': ['error', 2],
      'vue/html-quotes': ['error', 'double'],
      'vue/html-self-closing': [
        'error',
        {
          html: {
            component: 'always',
            normal: 'never',
            void: 'always'
          },
          math: 'always',
          svg: 'always'
        }
      ],
      'vue/max-attributes-per-line': 'off',
      'vue/multi-word-component-names': 'off',
      'vue/multiline-html-element-content-newline': 'error',
      'vue/no-empty-pattern': 'error',
      'vue/no-extra-parens': ['error', 'functions'],
      'vue/no-irregular-whitespace': 'error',
      'vue/no-loss-of-precision': 'error',
      'vue/no-reserved-component-names': 'off',
      'vue/no-restricted-syntax': ['error', 'DebuggerStatement', 'LabeledStatement', 'WithStatement'],
      'vue/no-restricted-v-bind': ['error', '/^v-/'],
      'vue/no-sparse-arrays': 'error',
      'vue/no-unused-refs': 'error',
      'vue/no-useless-v-bind': 'error',
      'vue/object-shorthand': [
        'error',
        'always',
        {
          avoidQuotes: true,
          ignoreConstructors: false
        }
      ],
      'vue/one-component-per-file': 'error',
      'vue/prefer-import-from-vue': 'error',
      'vue/prefer-separate-static-class': 'error',
      'vue/prefer-template': 'error',
      'vue/prop-name-casing': ['error', 'camelCase'],
      'vue/require-default-prop': 'off',
      'vue/require-explicit-emits': 'error',
      'vue/require-prop-types': 'off',
      'vue/singleline-html-element-content-newline': 'off',
      'vue/space-infix-ops': 'error',
      'vue/space-unary-ops': ['error', { nonwords: false, words: true }],
      'vue/v-on-event-hyphenation': [
        'error',
        'always',
        {
          autofix: true,
          ignore: []
        }
      ]
    }
  }
])
